package transactionService

import (
	"encoding/json"
	"errors"
	"github.com/spf13/cast"
	"hc_server/pkg/aes"
	"hc_server/pkg/channel"
	"hc_server/pkg/request"
	"hc_server/pkg/util"
	"hc_server/routers/models"
	"time"
)

type Transaction struct {
	MerchantId int     //商户号
	Type       int     //1-微信；2-支付宝；3-云闪付；5-聚分期；
	Amount     float32 //交易金额，单位为元，保留两位小数，取值范围[0.01,100000000]
	Openid     string  //微信、支付宝、云闪付的id
	Subject    string  //订单标题
	Body       string  //商品描述
	DeviceId   int     //设备id
	AuthCode   string  //客户付款码明文
}

// TransactionPay 联动用户交易接口
func (t *Transaction) TransactionPay() (map[string]interface{}, error) {
	//创建订单编号
	timeStr := cast.ToString(time.Now().Unix())
	randomStr := util.GenerateRandomStr(6)
	orderNo := timeStr + randomStr + cast.ToString(t.MerchantId)

	//通过deviceId获取设备信息,判断设备所绑定商户是否正确
	device, err := models.GetDeviceById(t.DeviceId)
	if err != nil {
		return nil, err
	}
	if cast.ToInt(device.MerchantId) != t.MerchantId {
		return nil, errors.New("设备信息错误，请重试")
	}
	if device.AgentId == 0 {
		return nil, errors.New("设备信息错误，请重试")
	}

	//获取商户信息
	merchant, err := models.MerchantByID(t.MerchantId)
	if err != nil {
		return nil, err
	}
	if len(merchant.LDMerchantId) == 0 {
		return nil, errors.New("交易失败")
	}

	//获取商户的费率
	rate, err := models.MerchantRateInfoByMerchantId(t.MerchantId)
	if err != nil {
		return nil, err
	}

	var PayRate float32
	var rateType int
	//支付方式:1-微信；2-支付宝；3-云闪付；5-聚分期；
	if t.Type == 1 {
		PayRate = cast.ToFloat32(rate.Wechat)
		rateType = 1
	} else if t.Type == 2 {
		PayRate = cast.ToFloat32(rate.Alipay)
		rateType = 2
	} else if t.Type == 3 {
		if t.Amount <= 1000 {
			PayRate = cast.ToFloat32(rate.YunPayMin)
			rateType = 3
		} else {
			PayRate = cast.ToFloat32(rate.YunPayMax)
			rateType = 4
		}
	} else {
		return nil, errors.New("暂不支持该支付方式")
	}

	payInfo, err := models.AgentRateGetRateInfoList(rateType, device.AgentId, PayRate)
	if err != nil {
		return nil, err
	}

	//生成本地订单
	models.MerchantOrderAdd(&models.MerchantOrder{
		MerchantId: t.MerchantId,
		AgentId:    device.AgentId,
		Amount:     t.Amount,
		Subject:    t.Subject,
		Body:       t.Body,
		Platform:   1,
		PayType:    t.Type,
		DeviceId:   t.DeviceId,
		OrderNo:    orderNo,
		Type:       1,
		PayRate:    PayRate,
		PayInfo:    payInfo,
	})

	//调用联动支付接口
	param := &channel.PayUnifyPayParam{
		MerchantId:  merchant.LDMerchantId,
		PayOrderNo:  orderNo,
		TransAmount: cast.ToString(t.Amount),
		TransType:   t.Type,
		PayType:     3,
		SubOpenid:   t.Openid,
		Subject:     t.Subject,
		Body:        t.Body,
	}
	result, err := channel.LianUnifyPay(param)
	if err != nil {
		return nil, err
	}

	//更新本地订单状态
	requestStr, _ := json.Marshal(&param)
	responseStr, _ := json.Marshal(&result)
	var typed int
	//订单状态：3-下单成功；4-支付成功；5-支付失败；
	switch cast.ToInt(result["orderStatus"]) {
	case 3:
		typed = 1
	case 4:
		typed = 2
	default:
		typed = 3
	}
	_, err = models.MerchantOrderUpdate(map[string]interface{}{"request": cast.ToString(requestStr), "response": cast.ToString(responseStr), "type": typed}, orderNo)
	if err != nil {
		return nil, err
	}

	if typed == 1 {
		//订单支付成功 给统计活跃商户添加数据 统计活跃天数
		err = models.AddMerchantOrderDynamicStatistics(t.MerchantId)
		if err != nil {
			return nil, err
		}
	}

	return result, nil
}

// TransactionPayCode 用户展示付款码交易
func (t *Transaction) TransactionPayCode() (map[string]interface{}, error) {
	//创建订单编号
	orderNo := cast.ToString(util.GenerateRandomStr(6)) + cast.ToString(time.Now().Unix()) + cast.ToString(t.MerchantId)
	//通过deviceId获取设备信息,判断设备所绑定商户是否正确
	device, err := models.GetDeviceById(t.DeviceId)
	if err != nil {
		return nil, err
	}
	if cast.ToInt(device.MerchantId) != t.MerchantId {
		return nil, errors.New("设备信息错误，请重试")
	}

	//获取商户信息
	merchant, err := models.MerchantByID(t.MerchantId)
	if err != nil {
		return nil, err
	}
	if len(merchant.LDMerchantId) == 0 {
		return nil, errors.New("交易失败")
	}

	//获取商户的费率
	rate, err := models.MerchantRateInfoByMerchantId(t.MerchantId)
	if err != nil {
		return nil, err
	}

	var PayRate float32
	var rateType int
	//支付方式:1-微信；2-支付宝；3-云闪付；5-聚分期；
	if t.Type == 1 {
		PayRate = cast.ToFloat32(rate.Wechat)
		rateType = 1
	} else if t.Type == 2 {
		PayRate = cast.ToFloat32(rate.Alipay)
		rateType = 2
	} else if t.Type == 3 {
		if t.Amount <= 1000 {
			PayRate = cast.ToFloat32(rate.YunPayMin)
			rateType = 3
		} else {
			PayRate = cast.ToFloat32(rate.YunPayMax)
			rateType = 4
		}
	} else {
		return nil, errors.New("暂不支持该支付方式")
	}

	payInfo, err := models.AgentRateGetRateInfoList(rateType, device.AgentId, PayRate)
	if err != nil {
		return nil, err
	}

	//生成本地订单
	models.MerchantOrderAdd(&models.MerchantOrder{
		AgentId:    merchant.AgentID,
		MerchantId: t.MerchantId,
		Amount:     t.Amount,
		Subject:    t.Subject,
		Body:       t.Body,
		Platform:   1,
		PayType:    t.Type,
		DeviceId:   t.DeviceId,
		OrderNo:    orderNo,
		Type:       1,
		PayRate:    PayRate,
		PayInfo:    payInfo,
	})

	//调用联动支付接口
	param := &channel.PayBarCodePayParam{
		MerchantId:  merchant.LDMerchantId,
		PayOrderNo:  orderNo,
		TransAmount: cast.ToString(t.Amount),
		TransType:   t.Type,
		PayType:     3,
		Subject:     t.Subject,
		Body:        t.Body,
		AuthCode:    t.AuthCode,
	}
	result, err := channel.LianBarCodePay(param)
	if err != nil {
		return nil, err
	}

	//更新本地订单状态
	requestStr, _ := json.Marshal(&param)
	responseStr, _ := json.Marshal(&result)
	var typed int
	switch cast.ToInt(result["orderStatus"]) {
	case 3:
		typed = 1
	case 4:
		typed = 2
	default:
		typed = 3
	}
	_, err = models.MerchantOrderUpdate(map[string]interface{}{"request": cast.ToString(requestStr), "response": cast.ToString(responseStr), "type": typed}, orderNo)
	if err != nil {
		return nil, err
	}

	return result, nil
}

// TransactionLianOrderList 订单查询
func (t *Transaction) TransactionLianOrderList() (map[string]interface{}, error) {
	//获取商户信息
	merchant, err := models.MerchantByID(t.MerchantId)
	if err != nil {
		return nil, err
	}
	if len(merchant.LDMerchantId) == 0 {
		return nil, errors.New("查询失败")
	}

	//调用联动支付接口
	param := &channel.OrderParam{
		MerchantId: merchant.LDMerchantId,
	}
	result, err := channel.LianOrder(param)
	if err != nil {
		return nil, err
	}
	return result, nil
}

// TransactionLianNotifyUrl 联动支付回调
func (t *Transaction) TransactionLianNotifyUrl(param *channel.NotifyUrlParam) error {
	// 将map转换为JSON格式的字符串
	jsonData, err := aes.AesCbcDecryptByBase64(cast.ToString(param.Data), []byte(request.AesPrivate), []byte(request.AesSecretKey))
	if err != nil {
		return err
	}

	resultByte, err := json.Marshal(jsonData)
	if err != nil {
		return err
	}

	//回调数据保存到表中，并且更新订单支付状态为成功
	result := cast.ToStringMap(resultByte)
	order, err := models.MerchantOrderUpdate(map[string]interface{}{"callback": cast.ToStringMap(jsonData), "type": 2}, result["payOrderNo"])
	if err != nil {
		return err
	}

	err = models.AgentIncomeLogAdd(order)
	if err != nil {
		return err
	}

	return nil
}

// TransactionLianNotifyUrl1 联动支付回调
func (t *Transaction) TransactionLianNotifyUrl1(callback, payOrderNo string) error {
	order, err := models.MerchantOrderUpdate(map[string]interface{}{"callback": callback, "type": 2}, payOrderNo)
	if err != nil {
		return err
	}

	err = models.AgentIncomeLogAdd(order)
	if err != nil {
		return err
	}

	return nil
}
